package com.xinchao.ck_mips.http;

import com.xinchao.ck_mips.constant.HttpConfig;
import com.xinchao.rxtools.rxhttp.tools.JsonUtils;

import io.reactivex.Flowable;
import io.reactivex.FlowableTransformer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Predicate;
import io.reactivex.schedulers.Schedulers;

/**
 * 网络请求的接口
 */
public class CKRequestUtils {

    /**
     * 请求网络
     */
    public static <T> void requestFromInternet(Flowable<CKResponse<T>> flowable, CKRequestSubscriber<T> listener) {
        request(flowable).subscribe(listener);
    }

    /**
     * 请求网络不回到主线程
     */
    public static <T> void requestFromInternetOnThread(Flowable<CKResponse<T>> flowable, CKRequestSubscriber<T> listener) {
        requestOnThread(flowable).subscribe(listener);
    }

    /**
     * 在当前线程请求数据
     */
    public static <T> void requestFromInternetOnCurrentThread(Flowable<CKResponse<T>> flowable, CKRequestSubscriber<T> listener) {
        requestCurrentThread(flowable).subscribe(listener);
    }


    private static <T> Flowable<CKResponse<T>> request(final Flowable<CKResponse<T>> flowable) {
        return flowable.compose(CKRequestUtils.<T>addFilter()).compose(CKRequestUtils.<CKResponse<T>>applySchedulers());
    }

    private static <T> Flowable<CKResponse<T>> requestOnThread(final Flowable<CKResponse<T>> flowable) {
        return flowable.compose(CKRequestUtils.<T>addFilter()).subscribeOn(Schedulers.io());
    }

    public static <T> Flowable<CKResponse<T>> requestCurrentThread(final Flowable<CKResponse<T>> flowable) {
        return flowable.compose(CKRequestUtils.<T>addFilter());
    }


    /**
     * 添加网络连接器
     */
    private static <T> FlowableTransformer<CKResponse<T>, CKResponse<T>> addFilter() {
        return upstream -> upstream.filter((Predicate<CKResponse<T>>) bean -> {
            // 过滤正常状态码
            switch (bean.getCode()) {
                case HttpConfig.StatusCode.SUCCESS:
                    return true;
                case HttpConfig.StatusCode.REGISTERED:
                    return true;
                case HttpConfig.StatusCode.VALIDATE_FAIL:
                    throw new RuntimeException(bean.getCode() + bean.getMsg());
                case HttpConfig.StatusCode.DENIED:
                    throw new RuntimeException(bean.getCode() + bean.getMsg());
                case HttpConfig.StatusCode.NOT_REGIST:
                    throw new RuntimeException(bean.getCode() + bean.getMsg());
                case HttpConfig.StatusCode.TOKEN_INVALID:
                    throw new RuntimeException(bean.getCode() + bean.getMsg());
                default:
                    throw new RuntimeException(JsonUtils.toJson(bean));
            }
        });
    }

    /**
     * 修改rx的线程
     */
    public static <T> FlowableTransformer<T, T> applySchedulers() {
        return upstream -> upstream.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }
}
